#include <map>
#include <nice2d/application.h>
#include <nice2d/background.h>
#include <nice2d/widgets/desktop.h>
#include <nice2d/widgets/menu.h>
#include <nice2d/widgets/linecontrol.h>

IMPLEMENT_OBJECT(MenuStyle, LayoutStyle)

MenuStyle::MenuStyle()
{
    normalBackground = Background::create(sf::Color(210, 210, 210, 250));
    hoverBackground = normalBackground;
    buttonStyle = std::make_shared<ButtonStyle>();
}

MenuStyle::~MenuStyle()
{
}

class MenuData
{
public:
    Menu *menu = nullptr;
    std::map<std::shared_ptr<BasicButton>, uint32_t> items;

    MenuData(Menu *thisMenu):
        menu(thisMenu)
    {
        auto desktop = GET_COMPONENT(Application::getInstance(), Desktop);
        auto style = desktop->getControlStyle("Menu");
        menu->setControlStyle(style);
    }

    void clickedItem(std::shared_ptr<BasicButton> button)
    {
        auto find = items.find(button);
        menu->clicked(find->second);
    }
};

IMPLEMENT_OBJECT(Menu, VBoxLayout)

Menu::Menu():
    data(new MenuData(this))
{
}

Menu::~Menu()
{
}

void Menu::addItem(const sf::String &item, uint32_t id)
{
    auto button = std::make_shared<Button>();
    button->setWidth(90);
    button->setText(item);
    addWidget(button);

    auto style = std::dynamic_pointer_cast<MenuStyle>(getControlStyle());
    button->setControlStyle(style->buttonStyle);

    button->pressed.connect([&](std::shared_ptr<BasicButton> button) {
        data->clickedItem(button);
    });
    data->items.insert_or_assign(button, id);
}

void Menu::addSeperator()
{
    auto seperator = std::make_shared<LineControl>();
    seperator->setLineWidth(1.0f);
    seperator->setOrientation(Orientation_H);
    seperator->setHResizeRule(ControlResizeRule_Fill);
    addWidget(seperator);
}

void Menu::onStyleChanged()
{
    auto style = std::dynamic_pointer_cast<MenuStyle>(getControlStyle());

    auto itr = data->items.begin();
    while (itr != data->items.end()) {
        itr->first->setControlStyle(style->buttonStyle);
        itr ++;
    }

    Layout::onStyleChanged();
}
